package com.hibernate.hrm.controller.department;

import com.hibernate.hrm.config.GlobalExceptionHandler;
import com.hibernate.hrm.entity.Department;
import com.hibernate.hrm.entity.User;
import com.hibernate.hrm.dao.DepartmentRepository;
import com.hibernate.hrm.entity.dto.department.*;
import com.hibernate.hrm.entity.dto.employee.UserDTO;
import com.hibernate.hrm.service.department.DepartmentService;
import jakarta.persistence.EntityNotFoundException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/department")
@RequiredArgsConstructor
public class DepartmentController {

    private final DepartmentService departmentService;
    private final DepartmentRepository departmentRepository;
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @GetMapping
    public String departmentListPage(@AuthenticationPrincipal User currentUser, Model model) {
        // 确保用户信息添加到模型
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());

        // 获取完整部门树
        List<Department> departmentTree = departmentService.getCompleteDepartmentTree(currentUser);
        model.addAttribute("departments", departmentTree);
        return "department";
    }

    @GetMapping("/api/departments/{id}/children")
    @ResponseBody
    public List<DepartmentDTO> getChildDepartments(@PathVariable Integer id) {
        Department parent = departmentRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("部门不存在"));

        // 获取子部门并转换为DTO
        List<Department> children = departmentRepository.findByDepartmentParentID(parent);
        return DepartmentDTO.fromEntities(children);
    }

    @PostMapping("toggle-status/{id}")
    public String toggleDepartmentStatus(
            @PathVariable("id") Integer departmentId,
            @AuthenticationPrincipal User currentUser,
            RedirectAttributes redirectAttributes,
            HttpServletRequest request) {

        try {
            Department department = departmentService.toggleDepartmentStatus(departmentId, currentUser);
            String action = department.getStatus() ? "启用" : "禁用";
            redirectAttributes.addFlashAttribute("success", "部门" + action + "成功");
        } catch (Exception e) {
            logger.error("部门状态切换失败: {}", e.getMessage(), e);
            redirectAttributes.addFlashAttribute("error", e.getMessage());
        }

        return "redirect:" + getSafeReferer(request);
    }

    private String getSafeReferer(HttpServletRequest request) {
        String referer = request.getHeader("Referer");
        return referer != null ? referer : "/department";
    }

    @PostMapping("/set-head/{id}")
    @ResponseBody
    public ResponseEntity<?> setDepartmentHead(
            @PathVariable("id") Integer departmentId,
            @RequestParam("headId") Integer headId,
            @AuthenticationPrincipal User currentUser) {

        try {
            departmentService.setDepartmentHead(departmentId, headId, currentUser);
            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "部门负责人设置成功"
            ));
        } catch (Exception e) {
            logger.error("设置部门负责人失败: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(Map.of(
                    "success", false,
                    "message", e.getMessage()
            ));
        }
    }

    @GetMapping("/set-head/{id}/candidates")
    @ResponseBody
    public ResponseEntity<?> getHeadCandidates(@PathVariable("id") Integer departmentId) {
        try {
            List<UserDTO> candidates = departmentService.findEligibleHeadCandidates(departmentId);
            return ResponseEntity.ok(candidates);
        } catch (Exception e) {
            logger.error("获取负责人候选列表失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of("error", "获取候选人列表失败"));
        }
    }

    @GetMapping("/view/{id}")
    public String viewDepartmentDetail(
            @PathVariable("id") Integer departmentId,
            @AuthenticationPrincipal User currentUser,
            Model model) {

        DepartmentDetailDTO department = departmentService.getDepartmentDetail(departmentId);
        model.addAttribute("department", department);
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());

        return "department-view";
    }

    @GetMapping("/edit/{id}")
    public String editDepartmentPage(
            @PathVariable("id") Integer departmentId,
            @AuthenticationPrincipal User currentUser,
            Model model) {

        Department department = departmentService.getDepartmentForEdit(departmentId);
        List<Department> availableParents = departmentService.getAvailableParentDepartments(departmentId);

        model.addAttribute("department", department);
        model.addAttribute("availableParents", availableParents);
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());

        return "department-edit";
    }

    @PostMapping("/edit/{id}")
    public String updateDepartment(
            @PathVariable("id") Integer departmentId,
            @ModelAttribute DepartmentEditDTO editDTO,
            @AuthenticationPrincipal User currentUser,
            RedirectAttributes redirectAttributes) {

        try {
            departmentService.updateDepartment(departmentId, editDTO, currentUser);
            redirectAttributes.addFlashAttribute("success", "部门信息更新成功");
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", e.getMessage());
            return "redirect:/department/edit/" + departmentId;
        }

        return "redirect:/department/view/" + departmentId;
    }

    //添加顶级部门
    @GetMapping("/add")
    public String showAddDepartmentPage(@AuthenticationPrincipal User currentUser, Model model) {
        List<UserDTO> eligibleHeads = departmentService.findEligibleDepartmentHeads();
        model.addAttribute("eligibleHeads", eligibleHeads);
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());
        return "department-add";
    }

    @PostMapping("/add")
    public String addTopDepartment(
            @ModelAttribute @Valid DepartmentAddDTO addDTO,
            BindingResult bindingResult,
            @AuthenticationPrincipal User currentUser,
            RedirectAttributes redirectAttributes) {

        if (bindingResult.hasErrors()) {
            return "department-add";
        }

        try {
            departmentService.addTopDepartment(addDTO, currentUser);
            redirectAttributes.addFlashAttribute("success", "顶级部门添加成功");
            return "redirect:/department";
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", e.getMessage());
            return "redirect:/department/add";
        }
    }

    //添加子部门
    @GetMapping("/add-child/{id}")
    public String showAddChildDepartmentPage(
            @PathVariable("id") Integer parentId,
            @AuthenticationPrincipal User currentUser,
            Model model) {

        Department parentDepartment = departmentService.getDepartmentForEdit(parentId);
        List<UserDTO> eligibleHeads = departmentService.findEligibleDepartmentHeads();

        model.addAttribute("parentDepartment", parentDepartment);
        model.addAttribute("eligibleHeads", eligibleHeads);
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());

        return "department-add-child";
    }

    @PostMapping("/add-child/{id}")
    public String addChildDepartment(
            @PathVariable("id") Integer parentId,
            @ModelAttribute @Valid DepartmentAddChildDTO addDTO,
            BindingResult bindingResult,
            @AuthenticationPrincipal User currentUser,
            RedirectAttributes redirectAttributes) {

        if (bindingResult.hasErrors()) {
            return "department-add-child";
        }

        try {
            departmentService.addChildDepartment(parentId, addDTO, currentUser);
            redirectAttributes.addFlashAttribute("success", "子部门添加成功");
            return "redirect:/department/view/" + parentId;
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", e.getMessage());
            return "redirect:/department/add-child/" + parentId;
        }
    }

    //删除部门
    @PostMapping("/delete/{id}")
    public String deleteDepartment(
            @PathVariable("id") Integer departmentId,
            @AuthenticationPrincipal User currentUser,
            RedirectAttributes redirectAttributes,
            HttpServletRequest request) {

        try {
            departmentService.deleteDepartment(departmentId, currentUser);
            redirectAttributes.addFlashAttribute("success", "部门删除成功");
        } catch (Exception e) {
            logger.error("删除部门失败: {}", e.getMessage(), e);
            redirectAttributes.addFlashAttribute("error", e.getMessage());
        }

        return "redirect:" + getSafeReferer(request);
    }
}
